package sdk

import (
	"context"
	"encoding/json"
	"fmt"
	"net/url"

	"github.com/yourusername/virt-manager-go/internal/models"
)

// StorageClient 提供存储管理相关的 API 操作
type StorageClient struct {
	client *APIClient
}

// NewStorageClient 创建新的存储客户端
func NewStorageClient(client *APIClient) *StorageClient {
	return &StorageClient{
		client: client,
	}
}

// ListStoragePools 列出指定连接的所有存储池
func (s *StorageClient) ListStoragePools(ctx context.Context, connectionID string) ([]models.StoragePoolSummary, error) {
	// 构建带查询参数的URL
	u := "/api/v1/storage/pools"
	if connectionID != "" {
		u = fmt.Sprintf("/api/v1/storage/pools?connection=%s", url.QueryEscape(connectionID))
	}

	data, err := s.client.Get(ctx, u)
	if err != nil {
		return nil, fmt.Errorf("failed to list storage pools for connection %s: %w", connectionID, err)
	}

	// API 返回的是包装格式 {"pools": [...], "count": n}
	var response struct {
		Pools []models.StoragePoolSummary `json:"pools"`
		Count int                         `json:"count"`
	}
	if err := json.Unmarshal(data, &response); err != nil {
		return nil, fmt.Errorf("failed to unmarshal storage pools response: %w", err)
	}

	return response.Pools, nil
}

// GetStoragePool 获取指定连接的存储池详情
func (s *StorageClient) GetStoragePool(ctx context.Context, connectionID, name string) (*models.StoragePoolDetail, error) {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/pool?connection=%s&pool=%s", url.QueryEscape(connectionID), url.QueryEscape(name))

	data, err := s.client.Get(ctx, u)
	if err != nil {
		return nil, fmt.Errorf("failed to get storage pool for connection %s: %w", connectionID, err)
	}

	var pool models.StoragePoolDetail
	if err := json.Unmarshal(data, &pool); err != nil {
		return nil, fmt.Errorf("failed to unmarshal storage pool: %w", err)
	}

	return &pool, nil
}

// CreateStoragePool 在指定连接创建新存储池
func (s *StorageClient) CreateStoragePool(ctx context.Context, connectionID string, xmlConfig string) error {
	// 构建带查询参数的URL
	u := "/api/v1/storage/pools"
	if connectionID != "" {
		u = fmt.Sprintf("/api/v1/storage/pools?connection=%s", url.QueryEscape(connectionID))
	}

	req := map[string]string{
		"xml_config": xmlConfig,
	}
	_, err := s.client.Post(ctx, u, req)
	if err != nil {
		return fmt.Errorf("failed to create storage pool for connection %s: %w", connectionID, err)
	}
	return nil
}

// DeleteStoragePool 删除指定连接的存储池
func (s *StorageClient) DeleteStoragePool(ctx context.Context, connectionID, name string) error {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/pool?connection=%s&pool=%s", url.QueryEscape(connectionID), url.QueryEscape(name))

	_, err := s.client.Delete(ctx, u)
	if err != nil {
		return fmt.Errorf("failed to delete storage pool for connection %s: %w", connectionID, err)
	}
	return nil
}

// StartStoragePool 启动指定连接的存储池
func (s *StorageClient) StartStoragePool(ctx context.Context, connectionID, name string) error {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/pool/start?connection=%s&pool=%s", url.QueryEscape(connectionID), url.QueryEscape(name))

	_, err := s.client.Post(ctx, u, nil)
	if err != nil {
		return fmt.Errorf("failed to start storage pool for connection %s: %w", connectionID, err)
	}
	return nil
}

// StopStoragePool 停止指定连接的存储池
func (s *StorageClient) StopStoragePool(ctx context.Context, connectionID, name string) error {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/pool/stop?connection=%s&pool=%s", url.QueryEscape(connectionID), url.QueryEscape(name))

	_, err := s.client.Post(ctx, u, nil)
	if err != nil {
		return fmt.Errorf("failed to stop storage pool for connection %s: %w", connectionID, err)
	}
	return nil
}

// ListStorageVolumes 列出指定连接存储池中的所有卷
func (s *StorageClient) ListStorageVolumes(ctx context.Context, connectionID, poolName string) ([]models.StorageVolumeSummary, error) {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/volumes?connection=%s&pool=%s", url.QueryEscape(connectionID), url.QueryEscape(poolName))

	data, err := s.client.Get(ctx, u)
	if err != nil {
		return nil, fmt.Errorf("failed to list storage volumes for connection %s: %w", connectionID, err)
	}

	var response struct {
		Volumes []models.StorageVolumeSummary `json:"volumes"`
		Count   int                           `json:"count"`
	}
	if err := json.Unmarshal(data, &response); err != nil {
		return nil, fmt.Errorf("failed to unmarshal storage volumes response: %w", err)
	}

	return response.Volumes, nil
}

// GetStorageVolume 获取指定连接存储池中存储卷的详情
func (s *StorageClient) GetStorageVolume(ctx context.Context, connectionID, poolName, volumeName string) (*models.StorageVolumeDetail, error) {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/volume?connection=%s&pool=%s&volume=%s", url.QueryEscape(connectionID), url.QueryEscape(poolName), url.QueryEscape(volumeName))

	data, err := s.client.Get(ctx, u)
	if err != nil {
		return nil, fmt.Errorf("failed to get storage volume for connection %s: %w", connectionID, err)
	}

	var volume models.StorageVolumeDetail
	if err := json.Unmarshal(data, &volume); err != nil {
		return nil, fmt.Errorf("failed to unmarshal storage volume: %w", err)
	}

	return &volume, nil
}

// CreateStorageVolume 在指定连接的存储池中创建新存储卷
func (s *StorageClient) CreateStorageVolume(ctx context.Context, connectionID, poolName string, req *models.CreateVolumeRequest) error {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/volumes?connection=%s&pool=%s", url.QueryEscape(connectionID), url.QueryEscape(poolName))

	_, err := s.client.Post(ctx, u, req)
	if err != nil {
		return fmt.Errorf("failed to create storage volume for connection %s: %w", connectionID, err)
	}
	return nil
}

// DeleteStorageVolume 删除指定连接存储池中的存储卷
func (s *StorageClient) DeleteStorageVolume(ctx context.Context, connectionID, poolName, volumeName string) error {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/volume?connection=%s&pool=%s&volume=%s", url.QueryEscape(connectionID), url.QueryEscape(poolName), url.QueryEscape(volumeName))

	_, err := s.client.Delete(ctx, u)
	if err != nil {
		return fmt.Errorf("failed to delete storage volume for connection %s: %w", connectionID, err)
	}
	return nil
}

// GetStoragePoolXML 获取指定连接存储池的 XML 配置
func (s *StorageClient) GetStoragePoolXML(ctx context.Context, connectionID, name string) (string, error) {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/pools/%s/xml?connection=%s", url.QueryEscape(name), url.QueryEscape(connectionID))

	data, err := s.client.Get(ctx, u)
	if err != nil {
		return "", fmt.Errorf("failed to get storage pool xml for connection %s: %w", connectionID, err)
	}

	return string(data), nil
}

// GetStorageVolumeXML 获取指定连接存储卷的 XML 配置
func (s *StorageClient) GetStorageVolumeXML(ctx context.Context, connectionID, poolName, volumeName string) (string, error) {
	// 构建带查询参数的URL
	u := fmt.Sprintf("/api/v1/storage/pools/%s/volumes/%s/xml?connection=%s", url.QueryEscape(poolName), url.QueryEscape(volumeName), url.QueryEscape(connectionID))

	data, err := s.client.Get(ctx, u)
	if err != nil {
		return "", fmt.Errorf("failed to get storage volume xml for connection %s: %w", connectionID, err)
	}

	return string(data), nil
}
